﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;

namespace 语音朗读机器人
{
    public class plugin//<--这里不能改
    {
        public static bool IsNogift = false;
        public static bool IsNoName = false;
        public static TTS _tts = new TTS();
        public static TTSAPIClass etts = new TTSAPIClass();
        #region 这个是软件调用的部分，请勿阻塞或者使用消息框。
        /// <summary>
        /// 软件主界面打开后触发start
        /// </summary>
        public void start()
        {
            if (!CheckTTSA())
            {
                Installer itl = new Installer();
                itl.ShowDialog();
                Environment.Exit(0);
            }
            else
            {
                etts.SMSG += Etts_SMSG;
                etts.Init();
                etts.SessionStart("tts.cloud.wangjing");
            }
            SendMSG("bot.oninit;", true);
            _tts.Switch = false;
            SendMSG("bot.onswitch(" + _tts.Switch + ");", true);
            //SendMSG("好消息！好消息！在插件管理器双击心脏可以获得更多设置哦！");
        }

        /// <summary>
        /// 软件关闭时触发stop
        /// </summary>
        public void stop()
        {
            if (_tts.mode==1)
            {
                etts.Shutdown();
            }
        }

        /// <summary>
        /// 弹幕来了触发dmshow
        /// </summary>
        /// <param name="logtext">弹幕信息</param>
        /// <param name="uid">用户ID</param>
        /// <param name="nickname">用户昵称</param>
        /// <param name="datetime">接收时间(弹幕接收方式2显示为“发送时间：xxx”)</param>
        /// <param name="admin">是否房管（格式：“房管：0或1”）</param>
        /// <param name="member">是否成员</param>
        /// <param name="vip">是否VIP老爷（格式：“会员：0或1”）</param>
        /// <param name="roomid">房间ID</param>
        /// <param name="extra_info">额外信息</param>
        public void dmshow(string logtext, string uid, string nickname, string datetime, string admin, string member, string vip, string roomid, string extra_info)
        {
            if (IsNogift&&uid=="gift")
            {
                return;
            }
            _tts.Speak(logtext, nickname, IsNoName);
        }

        /// <summary>
        /// 主程序会分享一些行为信息给插件，方便插件开发者知道主程序在干什么
        /// P.S.新的特性都会发送记录到这里
        /// </summary>
        /// <param name="logmsg"></param>
        public void ActionLog(string logmsg)
        {
            if (logmsg.IndexOf("[TTS]Start") > -1)
            {
                _tts.Switch = true;
                _tts.Speak("机器人启动");
                //SendMSG("bot.onswitch(" + _tts.Switch + ");", true);

            }
            if (logmsg.IndexOf("[TTS]Stop") > -1)
            {
                _tts.Stop();
                _tts.Switch = false;
                //SendMSG("bot.onswitch(" + _tts.Switch + ");", true);
            }
            if (logmsg== "[回调]声音播放完毕;"&&_tts.mode==1)
            {
                etts.CanSpeak = true;
            }
            if (logmsg.IndexOf("[TTS]SetRate") > -1)
            {
                string rate = logmsg.Substring(13).TrimEnd(';');
                _tts.SetRate(double.Parse(rate));
            }
            if (logmsg.IndexOf("[TTS]SetVol") > -1)
            {
                string vol = logmsg.Substring(12).TrimEnd(';');
                _tts.SetVol(double.Parse(vol));
            }
            Regex speakcontent = new Regex("\\[TTS\\](.*),(.*);");
            if (speakcontent.IsMatch(logmsg))
            {
                Match ex=speakcontent.Match(logmsg);
                _tts.Speak(ex.Groups[1].Value, ex.Groups[2].Value, IsNoName);
            }
            
        }

        private bool CheckTTSA()
        {
            if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory+"hci_tts.dll"))
            {
                return true;
            }
            return false;
        }
        #endregion

        /// <summary>
        /// 在插件管理器双击插件会触发admin
        /// </summary>
        public void admin()
        {
            BOTAdmin bta = new BOTAdmin();
            bta.ShowDialog();
        }

        private void Etts_SMSG(string msg,bool action =false)
        {
            SendMSG(msg, action);
        }

        #region 这块就不需要动了，除非你想研究
        public event EventHandler SMSG;
        /// <summary>
        /// 告诉UP主助手你要显示什么信息
        /// </summary>
        /// <param name="text">显示信息</param>
        /// <param name="action">是否行为，如果是标记为行为则由UP主助手后台处理行为而不显示，也不会输出到弹幕</param>
        private void SendMSG(string text, bool action = false)
        {
            string _text = "{dl_title}";
            if (action)
            {
                _text = "{action}";
            }
            SMSG(new object[] { _text + text }, null);
        }
        #endregion
    }
    public class TTS
    {
        dynamic spVoice = null;
        public bool Switch = true;//开关
        public int mode = 0;//0是系统默认，1是云tts
        #region 定义
        private const string HuiHui = "Micrsoft HUihui Desktop";
        private const string Zira = "Micrsoft Zira Desktop";
        private Queue<string> ttsas = new Queue<string>();
        delegate void BGJ(string h_text);
        private BGJ _bgj;
        private bool IsON = false;
        #endregion
        public TTS()
        {
            Type type = Type.GetTypeFromProgID("SAPI.SpVoice");
            spVoice = Activator.CreateInstance(type);
            spVoice.Rate = 0;
            //spVoice.SelectVoice(HuiHui);
        }
        private void _speak(string msg)
        {
            switch (mode)
            {
                case 0:
                    spVoice.Speak(msg);
                    break;
                case 1:
                    plugin.etts.tts_synth(msg);
                    break;
            }
        }
        public void Speak(string h_text = "", string u_nickname = "隐藏BOSS",bool NONAME=false)
        {
            if (Switch)
            {
                string say = "";
                if (NONAME)
                {
                    say = h_text.Trim("弹幕：".ToCharArray());
                }
                else
                {
                    say = u_nickname.Trim("昵称：".ToCharArray()) + "说" + h_text.Trim("弹幕：".ToCharArray());
                }
                ttsas.Enqueue(say);
                if (!IsON)
                {
                    _bgj = new BGJ(_speak);
                    _bgj.BeginInvoke(ttsas.Dequeue(), SpeekCallBack, null);
                    IsON = true;
                }
            }
        }

        private void SpeekCallBack(IAsyncResult ar)
        {
            if (ttsas.Count > 0)
            {
                string say = ttsas.Dequeue();
                _bgj.BeginInvoke(say, SpeekCallBack, null);
            }
            else
            {
                IsON = false;
            }

        }
        public void Stop()
        {
            ttsas.Clear();
            IsON = false;
        }
        public void SetVol(double vol)
        {
            //spVoice.Voice = spVoice.GetVoices(string.Empty, string.Empty).Item(2);　//设置发音人
            switch (mode)
            {
                case 0:
                    spVoice.Volume = vol;　//设置音量１～１００　(系统最大竟是的百分比) 
                    break;
                case 1:
                    plugin.etts.tts_setvol(vol);
                    break;
            }
            
        }
        public void SetRate(double rate)
        {
            switch (mode)
            {
                case 0:
                    spVoice.Rate = rate;　
                    break;
                case 1:
                    plugin.etts.tts_setspeed(rate);
                    break;
            }
        }
    }
    public class IniHelper
    {
        #region INI操作
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);

        private string ReadString(string section, string key, string def, string filePath)
        {
            StringBuilder temp = new StringBuilder(1024);

            try
            {
                GetPrivateProfileString(section, key, def, temp, 1024, filePath);
            }
            catch
            { }
            return temp.ToString();
        }
        /// <summary>
        /// 根据section，key取值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="keys"></param>
        /// <param name="filePath">ini文件路径</param>
        /// <returns></returns>
        public string ReadIniKeys(string section, string keys, string filePath)
        {
            return ReadString(section, keys, "", filePath);
        }

        /// <summary>
        /// 保存ini
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="filePath">ini文件路径</param>
        public void WriteIniKeys(string section, string key, string value, string filePath)
        {
            WritePrivateProfileString(section, key, value, filePath);
        }
        #endregion
    }
}
